'use strict'

const dbUtil = require('../util/dbUtil');
const mysqlUtil = require('../util/mysqlUtil');
const Q = require('q');
const multiparty = require('multiparty');
const fs = require('fs');
const constants = require('../util/constants');
const mailUtil = require('../util/mailUtil');
const mustache = require('../util/mustache');
const superagent = require('superagent');

/**
 * 查询
 */
let query = (req, res) => {
    let sql = "select sp.*, date_format(sp.create_time,'%Y-%m-%d %T') as create_time_display, date_format(sp.publish_time,'%Y-%m-%d %T') as publish_time_display, date_format(sp.test_time,'%Y-%m-%d %T') as test_time_display, ts.name test_status_display ";
    //sql += ",(select group_concat(pro.name) from t_ug_package_project upp left join t_ug_project pro on pro.id = upp.project_id where upp.package_id=sp.id) as bind_projects, ";
    sql += "from t_ug_simple_package sp ";
    sql += "left join t_ug_teststatus ts on ts.code=sp.test_status ";
    sql += "where 1=1 ";

    let searchVal = mysqlUtil.paramFilter(req.body.searchVal);

    if (req.body.confirm_publish != null && req.body.confirm_publish != '') {
        sql += " and sp.is_publish=" + mysqlUtil.escape(req.body.confirm_publish);
    }
    if (req.body.test_status != null && req.body.test_status != '') {
        sql += " and sp.test_status=" + mysqlUtil.escape(req.body.test_status);
    }
    if (req.body.leader_userid != null && req.body.leader_userid != '') {
        sql += " and sp.leader_userid=" + mysqlUtil.escape(req.body.leader_userid);
    }
    if (req.body.packageProjectId != null && req.body.packageProjectId != '') {
        sql += " and exists (select 1 from t_ug_package_project upp where upp.package_id=sp.id and upp.project_id=" + mysqlUtil.escape(req.body.packageProjectId) + ")";
    }
    if (searchVal != null && searchVal != '') {
        sql += " and (sp.name like '%" + searchVal + "%' or sp.module like '%" + searchVal + "%' or sp.description like '%" + searchVal + "%')";
    }

    sql += " order by sp.create_time desc";

    dbUtil.partitionQuery(sql, req, res);
};

/**
 * 查询升级包对应的升级项目
 */
let queryPackageProjects = (req, res) => {
    let packageIds = req.body.packageIds;

    // 查询数据
    let _query = () => {
        let deferred = Q.defer();
        let sql = 'select pp.package_id, p.code, p.name from t_ug_package_project pp left join t_ug_project p on p.id=pp.project_id where package_id in (' +
            packageIds + ') order by pp.package_id, p.code';

        mysqlUtil.exec(sql, [], (err, result) => {
            deferred.resolve(result);
        });
        return deferred.promise;
    };

    // 开始处理
    _query().done(data => {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ datas: data }));
    });
};

/**
 * 进入上传升级包页面
 */
let toUpload = (req, res) => {
    let deferred = Q.defer();

    // 检查上传文件路径
    let _checkFilePath = () => {
        mysqlUtil.exec("select * from t_config where name=?", [constants.UPGRADE_PACKAGE_FILE_PATH], (err, result) => {
            if (result.length == 0) {
                deferred.reject("Haven't configure the path of the upload"); // 还没有配置上传路径
            } else {
                let folder_exists = fs.existsSync(result[0].value);
                if (!folder_exists) {
                    deferred.reject("Configuration of the upload path is wrong"); //配置的上传路径有误
                } else {
                    deferred.resolve(result[0].value);
                }
            }
        });
        return deferred.promise;
    };

    _checkFilePath().done(data => {
        res.render('simpleUpgradePackage/toUpload', {});
    }, data => {
        console.log(data);
        res.render('404_dialog', { errMsg: data });
    });

};

/**
 * 处理上传升级包
 */
let doUpload = (req, res) => {
    // 1. 获取上传文件路径
    let _getFilePath = () => {
        let deferred = Q.defer();

        let params = [constants.UPGRADE_PACKAGE_FILE_PATH];
        mysqlUtil.exec("select * from t_config where name in (?)", [params], (err, result) => {
            var obj = {};
            for (let r of result) {
                if (r.name === constants.UPGRADE_PACKAGE_FILE_PATH) {
                    obj.uploadPath = r.value;
                }
            }
            deferred.resolve(obj);
        });
        return deferred.promise;
    };

    // 2. 上传文件
    let _uploadFile = data => {
        let deferred = Q.defer();
        let form = new multiparty.Form(); // 解析一个文件上传
        form.encoding = 'utf-8'; //设置编码
        form.uploadDir = data.uploadPath; //设置文件存储路径
        form.maxFilesSize = 200 * 1024 * 1024; //设置单文件大小限制，form.maxFields = 1000;  设置所以文件的大小总和
        form.parse(req, (err, fields, files) => {
            let file = files.file1[0];
            let obj = {
                uploadPath: data.uploadPath,
                originalFilename: file.originalFilename,
                filePath: file.path,
                fileName: file.path.substring(file.path.lastIndexOf(constants.PATH_SEPARATOR) + 1, file.path.length)
            };
            deferred.resolve(obj);
        });
        return deferred.promise;
    };

    // 3.保存升级包信息
    let _insertData = data => {
        let deferred = Q.defer();

        let sql = 'insert into t_ug_simple_package(id, name, create_userid, create_username, create_time, is_publish, ';
        sql += 'is_need_reboot, is_need_clearcache, is_need_delfile, file_name, file_path, test_status, leader_userid, leader_username) values(uuid(), ?, ?, ?, now(), 0, 1, 0, 0, ?, ?, ?, ?, ?)';

        mysqlUtil.exec(sql, [data.originalFilename, req.session.user.id, req.session.user.name, data.fileName, data.filePath, '0', req.session.user.id, req.session.user.name], (err, result) => {
            deferred.resolve(data);
        });

        return deferred.promise;
    };

    // 开始处理
    _getFilePath().then(_uploadFile).then(_insertData).done(data => {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: true }));
    }, (data) => {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: false }));
    });
};

/**
 * 批量修改升级包
 */
let toBatchUpPackage = (req, res) => {
    var ids = req.query.ids;

    var data = {};
    var _getInfo = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select * from t_ug_simple_package where id in (?)", [ids.split(',')], (err, result) => {
            data.packages = result;
            deferred.resolve();
        });
        return deferred.promise;
    };

    var _getDevelopers = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select * from t_user where is_developer=1 order by code asc", [], (err, result) => {
            data.developers = result;
            deferred.resolve();
        });
        return deferred.promise;
    };

    _getInfo().then(_getDevelopers).done(function() {
        res.render('simpleUpgradePackage/toBatchUpPackage', data);
    });
};

/**
 *  处理批量修改升级包
 */
let doBatchUpPackage = (req, res) => {
    let packagesJson = req.body.packagesJson;

    let _updateInfo = () => {
        let deferred = Q.defer();
        var packages = JSON.parse(packagesJson);

        let sqlObjs = [];
        for (var i = 0; i < packages.length; i++) {
            sqlObjs.push({
                sql: 'update t_ug_simple_package set description=?, special_remark=?, module=?, is_need_reboot=?, is_need_clearcache=?, is_need_delfile=?, leader_userid=? where id=?',
                values: [packages[i].description, packages[i].special_remark, packages[i].module,
                    packages[i].is_need_reboot, packages[i].is_need_clearcache,
                    packages[i].is_need_delfile, packages[i].leader_userid, packages[i].id
                ]
            });
            sqlObjs.push({
                sql: 'update t_ug_simple_package set leader_username=(select name from t_user where id=leader_userid) where id=?',
                values: [packages[i].id]
            });
        }

        mysqlUtil.exec_batch(sqlObjs, null, function() {
            deferred.resolve();
        });
        return deferred.promise;
    };

    _updateInfo().done(data => {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: true }));
    });
};


/**
 * 更新测试状态
 */
let doUpdateTestStatu = (req, res) => {
    let packagesJson = req.body.packagesJson;

    let _updateInfo = () => {
        let deferred = Q.defer();
        var packages = JSON.parse(packagesJson);

        let sqlObjs = [];
        for (var i = 0; i < packages.length; i++) {
            sqlObjs.push({
                sql: 'update t_ug_simple_package set test_status=?, test_userid=?, test_username=?, test_time=now() where id=?',
                values: [packages[i].test_status, req.session.user.id, req.session.user.name, packages[i].id]
            });
        }

        mysqlUtil.exec_batch(sqlObjs, null, function() {
            deferred.resolve();
        });
        return deferred.promise;
    };

    _updateInfo().done(data => {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: true }));
    });
};

/**
 * 批量修改升级包测试结果
 */
let toUpdateTestResult = (req, res) => {
    var ids = req.query.ids;

    var _getInfo = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select * from t_ug_simple_package where id in (?)", [ids.split(',')], (err, result) => {
            deferred.resolve(result);
        });
        return deferred.promise;
    };

    _getInfo().done(function(data) {
        res.render('simpleUpgradePackage/toUpdateTestResult', { packages: data });
    });
};

/**
 *  处理批量修改升级包测试结果
 */
let doUpdateTestResult = (req, res) => {
    let packagesJson = req.body.packagesJson;

    function convertNull(obj) {
        return obj === '' ? null : obj;
    }

    let _updateInfo = () => {
        let deferred = Q.defer();
        var packages = JSON.parse(packagesJson);

        let sqlObjs = [];
        for (var i = 0; i < packages.length; i++) {
            var defect_count = convertNull(packages[i].defect_count);
            var high_defect_count = convertNull(packages[i].high_defect_count);
            var rework_count = convertNull(packages[i].rework_count);
            var demand_point_count = convertNull(packages[i].demand_point_count);

            sqlObjs.push({
                sql: 'update t_ug_simple_package set defect_count=?, high_defect_count=?, rework_count=?, demand_point_count=? where id=?',
                values: [defect_count, high_defect_count, rework_count, demand_point_count, packages[i].id]
            });
        }

        mysqlUtil.exec_batch(sqlObjs, null, function() {
            deferred.resolve();
        });
        return deferred.promise;
    };

    _updateInfo().done(data => {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: true }));
    });
};

/**
 * 绑定项目
 */
let toBindProject = (req, res) => {
    res.render('simpleUpgradePackage/toBindProject', { id: req.query.id });
};

/**
 * 处理绑定项目
 */
let doBindProject = (req, res) => {
    let projectsJson = req.body.projectsJson;
    let packageId = req.body.id;

    let _delRefProjects = () => {
        let deferred = Q.defer();
        mysqlUtil.exec('delete from t_ug_package_project where package_id=?', [packageId], (err, result) => {
            deferred.resolve();
        });
        return deferred.promise;
    };

    let _insRefProjects = () => {
        let deferred = Q.defer();
        var projects = JSON.parse(projectsJson);

        let sqlObjs = [];
        for (var i = 0; i < projects.length; i++) {
            sqlObjs.push({ sql: 'insert into t_ug_package_project(id, package_id, project_id) values(uuid(), ?, ?)', values: [packageId, projects[i].id] });
        }

        mysqlUtil.exec_batch(sqlObjs, null, function() {
            deferred.resolve();
        });
        return deferred.promise;
    };

    _delRefProjects().then(_insRefProjects).done(function() {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: true }));
    }, function() {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: false }));
    });
};

/**
 * 获取升级包关联的项目
 */
let getPackageProject = (req, res) => {
    var id = req.query.id;

    var output = {};

    var _getRelationProjects = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select p.id, p.name from t_ug_package_project upp left join t_ug_project p on p.id = upp.project_id where upp.package_id=?", [id], (err, result) => {
            output.relationProjects = result;
            deferred.resolve();
        });
        return deferred.promise;
    };

    var _getUnRelationProjects = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select id, name from t_ug_project p where p.id not in (select upp.project_id from t_ug_package_project upp where upp.package_id=?)", [id], (err, result) => {
            output.unRelationProjects = result;
            deferred.resolve();
        });
        return deferred.promise;
    };

    _getRelationProjects().then(_getUnRelationProjects).done(function() {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify(output));
    });
};

/**
 * 下载上传的压缩包
 */
let downloadZipFile = (req, res) => {
    let id = req.query.id;

    // 获取下载文件的路径及名称
    let _getFilePath = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select * from t_ug_simple_package where id=?", [id], (err, result) => {
            if (err || result.length == 0) {
                res.render('404', { errMsg: 'Can\'t find the file.' });
                return;
            }
            deferred.resolve({ filePath: result[0].file_path, fileName: result[0].name });
        });
        return deferred.promise;
    };

    _getFilePath().done(d => {
        res.download(d.filePath, d.fileName);
    });
};

/**
 * 删除升级包
 */
let remove = (req, res) => {
    let id = req.body.id; // packageId

    // 1. 获取升级包信息
    let _getPackage = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select * from t_ug_simple_package where id=?", [id], (err, result) => {
            deferred.resolve(result[0]);
        });
        return deferred.promise;
    };

    // 2. 删除物理文件
    let _removePackageFile = (data) => {
        let deferred = Q.defer();

        fs.unlink(data.file_path, function(err) {
            console.log(err);
            deferred.resolve();
        });
        return deferred.promise;
    };

    // 3. 删除数据
    let _deletePackage = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("delete from t_ug_simple_package where id=?", [id], (err, result) => {
            deferred.resolve();
        });
        return deferred.promise;
    };

    _getPackage().then(_removePackageFile).then(_deletePackage).done(function() {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: true }));
    }, function() {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: false }));
    });
};

/**
 * 发布升级包
 */
let publish = (req, res) => {
    let id = req.body.id; // packageId

    let dataObj = {};

    let _updatePackage = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("update t_ug_simple_package set is_publish=1, publish_userid=?, publish_username=?, publish_time=now() where id=?", [req.session.user.id, req.session.user.name, id], (err, result) => {
            deferred.resolve();
        });
        return deferred.promise;
    };

    // 获取需要接收邮件的人
    let _getReceiver = () => {
        let deferred = Q.defer();

        let sql = "select * from (select p.leader_mails as leader_mails from t_ug_simple_package sp ";
        sql += "left join t_ug_package_project upp on upp.package_id=sp.id left join t_ug_project p on p.id = upp.project_id ";
        sql += "where sp.id=? group by p.leader_mails) datas union select mail from t_user where id=?";

        mysqlUtil.exec(sql, [id, req.session.user.id], (err, result) => {
            let receivers = [];
            for (let i = 0; i < result.length; i++) {
                receivers.push(result[i].leader_mails);
            }

            dataObj.to = receivers.join(','); // 收件人
            deferred.resolve();
        });
        return deferred.promise;
    };

    // 获取升级包信息
    let _getPackageInfo = () => {
        let deferred = Q.defer();

        let sql = "select sp.*, sp.name as package_name, ";
        sql += "date_format(sp.create_time,'%Y-%m-%d %T') as create_time_display, date_format(sp.publish_time,'%Y-%m-%d %T') as publish_time_display, ";
        sql += "(select group_concat(p.name) from t_ug_package_project upp left join t_ug_project p on p.id = upp.project_id where sp.id=upp.package_id) as project_name ";
        sql += "from t_ug_simple_package sp where sp.id=?";

        mysqlUtil.exec(sql, [id], (err, result) => {
            let r = result[0];
            console.log(r);
            dataObj.subject = '升级包-' + r.project_name + '-' + r.package_name; // 标题
            deferred.resolve(r);
        });

        return deferred.promise;
    };

    // 发送邮件
    let _sendMail = (data) => {
        let deferred = Q.defer();
        let tpl = `
            <style>
                .my-table { border-collapse:collapse; width:700px; word-wrap:break-word;word-break:break-all;margin-bottom:4px; }
                .my-table tr { height:32px; }
                .my-table td { border:1px solid #000; font-size:12px; padding-left:4px;padding-right:4px; line-height:20px; } 
                .mt { background: #e6e8e9; text-align:center; padding:0; }
            </style>
            <div style="font-size:12px;">
                <div style="margin-bottom:12px;">您好，请及时查收升级包并进行升级。升级平台访问地址：http://yjs.wisedu.com</div>
                
                <table class="my-table">
                    <tr>
                        <td class="mt" style="width:20%">所属项目</td>
                        <td style="width:30%;font-weight:bold;">{{project_name}}</td>
                        <td class="mt" style="width:20%">升级包名</td>
                        <td style="width:30%">{{name}}</td>
                    </tr>
                    <tr>
                        <td class="mt">描述</td>
                        <td colspan="3">{{description}}</td>
                    </tr>
                    <tr>
                        <td class="mt">是否重启</td>
                        <td>{{#is_need_reboot}}<font color='red'>重启</font>{{/is_need_reboot}}{{^is_need_reboot}}无需重启{{/is_need_reboot}}</td>
                        <td class="mt">是否清除weblogic缓存</td>
                        <td>{{#is_need_clearcache}}<font color='red'>清除</font>{{/is_need_clearcache}}{{^is_need_clearcache}}无需清除{{/is_need_clearcache}}</td>
                    </tr>
                    <tr>
                        <td class="mt">是否先删除服务器文件</td>
                        <td>{{#is_need_delfile}}<font color='red'>删除</font>{{/is_need_delfile}}{{^is_need_delfile}}无需删除{{/is_need_delfile}}</td>
                        <td class="mt">是否手工执行脚本</td>
                        <td>{{#is_need_exescript}}<font color='red'>执行</font>{{/is_need_exescript}}{{^is_need_exescript}}无需执行{{/is_need_exescript}}</td>
                    </tr>
                    <tr>
                        <td class="mt">责任人</td>
                        <td colspan="3"><b>{{leader_username}}</b></td>
                    </tr>
                    <tr>
                        <td class="mt">创建人</td>
                        <td>{{create_username}}</td>
                        <td class="mt">创建时间</td>
                        <td>{{create_time_display}}</td>
                    </tr>
                    <tr>
                        <td class="mt">发布人</td>
                        <td>{{publish_username}}</td>
                        <td class="mt">发布时间</td>
                        <td>{{publish_time_display}}</td>
                    </tr>
                </table>
            </div>`;
        let html = mustache.render(tpl, data);
        dataObj.html = html;

        mailUtil.sendMail(dataObj, function(isSuccess) {});
        deferred.resolve();
        return deferred.promise;
    };

    let _sendDdMsg = (data) => function() {
        let deferred = Q.defer();

        var content = '@15240249259 @15195882308 升级包名：' + data.name + '，描述：' + data.description + '，请及时查收升级包并在测试环境进行同步，谢谢！';
        console.log(content);
        superagent.post('https://oapi.dingtalk.com/robot/send?access_token=207bb34283a65d0a5802516e2d698e3c6ea6912add990f40f1bc237522d5121c').send({
            "msgtype": "text",
            "text": {
                "content": content
            },
            "at": {
                "atMobiles": [
                    "15240249259", "15195882308"
                ],
                "isAtAll": false
            }
        }).end(function(err, res) {
            console.log(res);
            deferred.resolve();
        });
        return deferred.promise;
    };

    _updatePackage().then(_getReceiver).then(_getPackageInfo).then(_sendMail).then(_sendDdMsg).done(function() {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: true }));
    }, function() {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: false }));
    });
};


exports.query = query;
exports.queryPackageProjects = queryPackageProjects;
exports.toUpload = toUpload;
exports.doUpload = doUpload;
exports.toBatchUpPackage = toBatchUpPackage;
exports.doBatchUpPackage = doBatchUpPackage;
exports.doUpdateTestStatu = doUpdateTestStatu;
exports.toUpdateTestResult = toUpdateTestResult;
exports.doUpdateTestResult = doUpdateTestResult;
exports.toBindProject = toBindProject;
exports.doBindProject = doBindProject;
exports.getPackageProject = getPackageProject;
exports.downloadZipFile = downloadZipFile;
exports.publish = publish;
exports.remove = remove;